<template>
  <el-popover :width="400" trigger="click" v-model:visible="popVisible">
    <template #reference>
      <el-input
        v-model="inputVal"
        :readonly="!props.filterable"
        :disabled="props.disabled"
        type="text"
        class="pop-input"
        placeholder="请选择图标"
        @input="handeInput"
        @focus="popVisible = true"
        @mouseenter="inputHovering = true"
        @mouseleave="inputHovering = false"
        @click.stop
      >
        <template #prefix>
          <div class="select-icon" @click.stop="popVisible = true">
            <SvgIcon v-if="selIcon" :font="selIcon" :size="14" />
            <el-icon v-else>
              <Tools />
            </el-icon>
          </div>
        </template>
        <template #suffix>
          <el-icon v-if="showClose" class="input__icon icon-circle-close" @click.stop="handleClearClick">
            <CircleClose />
          </el-icon>
          <el-icon v-else class="input__icon icon-arrow-down" :class="{ 'is-reverse': popVisible}" @click.stop="popVisible = true">
            <ArrowDown />
          </el-icon>
        </template>
      </el-input>
    </template>
    <div class="icon-list">
      <div
        v-for="icon in svgList"
        :key="icon.icon_id"
        class="icon-item"
        @click="handeleSelect(icon)"
      >
        <SvgIcon :font="icon.font_class" :size="20" />
        <div class="desc">
          <p :title="icon.name">
            {{ icon.name }}
          </p>
          <p :title="icon.font_class">
            {{ icon.font_class }}
          </p>
        </div>
      </div>
    </div>
  </el-popover>
</template>

<script lang="ts" setup>
import '@/assets/defaultIcon/iconfont.js'
import '@/assets/icon/iconfont.js'
import { glyphs as defaultIcons } from '@/assets/defaultIcon/iconfont.json'
import { glyphs as Icons } from '@/assets/icon/iconfont.json'
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'
import { ArrowDown, CircleClose, Tools } from '@element-plus/icons'
const glyphs = [...defaultIcons, ...Icons]
const props = defineProps({
  modelValue: {
    type: String,
    default: ''
  },
  disabled: Boolean,
  filterable: Boolean,
  clearable: Boolean
})
// 事件
const emit = defineEmits(['update:modelValue'])
// 图标列表
const svgList = ref(glyphs)
// 控制显示
const popVisible = ref(false)
// input值
const inputVal = ref('')
// 鼠标悬停
const inputHovering = ref(false)
// 选择的icon
const selIcon = ref('')
// 控制显示清除
const showClose = computed(() => props.clearable && inputVal.value && inputHovering.value)
// 选中事件
const handeleSelect = (icon: any) => {
  if (typeof icon === 'string') icon = glyphs.find(item => item.font_class === props.modelValue)
  if (icon) {
    svgList.value = glyphs
    inputVal.value = icon.name
    selIcon.value = icon.font_class
    popVisible.value = false
    emit('update:modelValue', selIcon.value)
  } else {
    handleClearClick()
  }
}
// 清除内容
const handleClearClick = () => {
  inputVal.value = ''
  selIcon.value = ''
  emit('update:modelValue', '')
  handeInput()
}
// 搜索输入事件
const handeInput = () => {
  svgList.value = glyphs.filter(item => item.name.includes(inputVal.value))
}
handeleSelect(props.modelValue)

const closePopover = () => {
  if (popVisible.value) {
    popVisible.value = false
  }
}

onMounted(() => {
  const formEle = document.querySelectorAll('.dialog-form')
  formEle.forEach(item => {
    item.addEventListener('click', closePopover)
  })
  document.addEventListener('click', closePopover)
})
onBeforeUnmount(() => {
  const formEle = document.querySelectorAll('.dialog-form')
  formEle.forEach(item => {
    item.removeEventListener('click', closePopover)
  })
  document.removeEventListener('click', closePopover)
})

watch(() => props.modelValue, val => {
  handeleSelect(val)
})
</script>

<style lang="scss" scoped>
.pop-input {
  .input__icon {
    width: 25px;
    line-height: 36px;
    height: inherit;
    display: flex;
    justify-content: center;
    align-items: center;
    cursor: pointer;
  }
  .icon-circle-close {
    &:hover {
      color: var(--el-input-clear-hover-color, var(--el-text-color-secondary));
    }
  }
  .icon-arrow-down {
    transition: var(--el-transition-all);
    height: calc(100% - 2px);
    font-size: 14px;
    &.is-reverse {
      transform: rotateZ(180deg);
    }
  }
  :deep(input) {
    cursor: pointer;
  }
}
.select-icon {
  display: flex;
  align-items: center;
  color: var(--el-text-color-regular);
}
.icon-list {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  width: 100%;
  height: 200px;
  border-top: 1px solid var(--el-border-color-lighter);
  border-left: 1px solid var(--el-border-color-lighter);
  overflow: auto;
  .icon-item {
    width: inherit;
    height: max-content;
    padding: 10px;
    text-align: center;
    font-style: inherit;
    color: var(--el-text-color-regular);
    border-right: 1px solid var(--el-border-color-lighter);
    border-bottom: 1px solid var(--el-border-color-lighter);
    box-sizing: border-box;
    overflow: hidden;
    &:hover {
      color: var(--el-color-primary);
      cursor: pointer;
    }
    .desc {
      margin-top: 10px;
      line-height: 1.5em;
      p {
        white-space:nowrap;
        overflow:hidden;
        text-overflow:ellipsis;
      }
    }
  }
}
</style>
